package alpaca.view.panels;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.TitledBorder;

import net.miginfocom.swing.MigLayout;
import alpaca.core.IUser;
import alpaca.ctrl.ControllerFactory;
import alpaca.ctrl.StartCtrl;
import alpaca.ctrl.StopCtrl;
import alpaca.util.DBConfigData;

public class StatusPanel extends JPanel {
	private JSpinner portTextField;
	private JButton toggleButton;
	private JLabel statusLabel;
	private JLabel hostnameLabel;
	private JLabel connectedLabel;
	private JPanel panel;
	private JLabel connectedAmountLabel;
	private JPanel panel_1;
	private JList list;
	private JScrollPane scrollPane;
	private DefaultListModel listModel;
	private boolean serverState = false;
	private final Action toggleAction = new ToggleAction();
	private JPanel panel_2;
	private JLabel lblNewLabel_1;
	private JTextField usernameTextField;
	private JLabel lblNewLabel_2;
	private JTextField dbURLTextField;
	private JLabel lblNewLabel_3;
	private JPasswordField passwordTextField;

	/**
	 * Create the panel.
	 * @throws UnknownHostException 
	 */
	public StatusPanel() {
		setLayout(new MigLayout("", "[46px,grow]", "[80px][30px][grow]"));
		
		panel = new JPanel();
		panel.setBorder(new TitledBorder(null, "Server Status", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		add(panel, "cell 0 0,grow");
		panel.setLayout(new MigLayout("", "[120px:120px,grow,center][50px,grow][100px,grow][100px,grow]", "[9px,grow][9px,grow]"));
		
		statusLabel = new JLabel("Server is not running");
		panel.add(statusLabel, "cell 0 0,alignx center,aligny center");
		
		JLabel lblNewLabel = new JLabel("Port: ");
		panel.add(lblNewLabel, "cell 1 0,alignx right,aligny center");
		
		toggleButton = new JButton(toggleAction);
		toggleButton.setMnemonic(KeyEvent.VK_T);
		toggleButton.setDisplayedMnemonicIndex(1);
		
		toggleButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
			}
		});
		portTextField = new JSpinner();
		portTextField.setModel(new SpinnerNumberModel(3141, 1, 65535, 1));

		panel.add(portTextField, "cell 2 0,alignx left,aligny center");
		panel.add(toggleButton, "cell 3 0 1 2,grow");
		hostnameLabel = new JLabel();
		try {
			hostnameLabel.setText(InetAddress.getLocalHost().getHostAddress());
		} catch (UnknownHostException e) {
			hostnameLabel.setText("Could not resolve IP");
		}
		panel.add(hostnameLabel, "cell 0 1,alignx center,aligny center");
		connectedLabel = new JLabel("Connected:");
		panel.add(connectedLabel, "cell 1 1,alignx trailing,aligny center");
		
		connectedAmountLabel = new JLabel("0");
		panel.add(connectedAmountLabel, "cell 2 1");
		
		panel_2 = new JPanel();
		panel_2.setBorder(new TitledBorder(null, "Database Settings", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		add(panel_2, "cell 0 1,grow");
		panel_2.setLayout(new MigLayout("", "[46px][130px][][130px,fill]", "[][14px,grow]"));
		
		dbURLTextField = new JTextField();
		panel_2.add(dbURLTextField, "cell 1 0 3 1,growx");
		dbURLTextField.setColumns(10);
		
		
		lblNewLabel_1 = new JLabel("User:");
		panel_2.add(lblNewLabel_1, "cell 0 1,alignx trailing,aligny top");
		
		lblNewLabel_2 = new JLabel("URL:");
		panel_2.add(lblNewLabel_2, "cell 0 0,alignx trailing");
		
		usernameTextField = new JTextField();
		panel_2.add(usernameTextField, "cell 1 1,growx");
		usernameTextField.setColumns(10);
		
		lblNewLabel_3 = new JLabel("Password:");
		panel_2.add(lblNewLabel_3, "cell 2 1,alignx right");
		
		passwordTextField = new JPasswordField();
		panel_2.add(passwordTextField, "cell 3 1,growx");
		passwordTextField.setColumns(10);
		
		panel_1 = new JPanel();
		panel_1.setBorder(new TitledBorder(null, "Connected Users", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		add(panel_1, "cell 0 2,grow");
		panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.X_AXIS));
		
		scrollPane = new JScrollPane();
		panel_1.add(scrollPane);
		
		list = new JList();
		list.setLayoutOrientation(JList.VERTICAL_WRAP);
		listModel = new DefaultListModel();
		list.setModel(listModel);
		scrollPane.setViewportView(list);
		
	}

	public void setStatus(Boolean serverstate) {
		this.serverState = serverstate;
		if (this.serverState){
			toggleAction.setEnabled(true);
			setStatusText("Server is running");
			toggleAction.putValue(Action.NAME, "Stop Server");
			portTextField.setEnabled(false);
			passwordTextField.setEnabled(false);
			dbURLTextField.setEnabled(false);
			usernameTextField.setEnabled(false);
		}else {
			toggleAction.setEnabled(true);
			setStatusText("Server is not running");
			toggleAction.putValue(Action.NAME, "Start Server");
			portTextField.setEnabled(true);
			passwordTextField.setEnabled(true);
			dbURLTextField.setEnabled(true);
			usernameTextField.setEnabled(true);
		}
	}
	
	public void setStatusText(String s) {	
		this.statusLabel.setText(s);
	}
	
	public void setHostnameText(String s) {
		this.hostnameLabel.setText(s);
	}

	public void setConnectedText(String s) {
		this.connectedAmountLabel.setText(s);
	}
	
	public void addUserList(Set<IUser> set){
	    listModel.clear();

		Iterator<IUser> iter = set.iterator();
	    while (iter.hasNext()) {
	      listModel.addElement(iter.next());
	    }
	}
	//To be used for efficiency, same in UserPanel and LogPanel
	public void addUserToList(String email){
		listModel.addElement(email);
	}
	//To be used for efficiency, same in UserPanel and LogPanel
	public void removeUserToList(String email){
		listModel.removeElement(email);
	}
	
	public void setDBConfigData(DBConfigData data) {
		dbURLTextField.setText(data.getDb());
		usernameTextField.setText(data.getUser());
		passwordTextField.setText(data.getPassword());
	}
	
	private class ToggleAction extends AbstractAction {
		public ToggleAction() {
			putValue(NAME, "Start Server");
			putValue(SHORT_DESCRIPTION, "Starts and stops the server");
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			if (serverState){
				ControllerFactory.getController(StopCtrl.class).execute();
			}else {
				Thread connectionThread = new Thread() {
					@Override
					public void run() {
						StartCtrl startServer = (StartCtrl)ControllerFactory.getController(StartCtrl.class);
						startServer.setPort((Integer) portTextField.getValue());
						DBConfigData data = new DBConfigData(dbURLTextField.getText(), 
								usernameTextField.getText(), 
								new String(passwordTextField.getPassword()));
						startServer.setDBConfigData(data);
						startServer.execute();
					}
				};
				connectionThread.start();

				toggleAction.putValue(Action.NAME, "Connecting...");
				toggleAction.setEnabled(false);
			}
		}
	}

	
}
